home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / WINDOWS / LENGINE.ZIP / DRAWTRI.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-12  |  5.1 KB  |  243 lines

  1. #include "header.h"
  2.  
  3. extern DirectDraw     *DD;
  4. extern unsigned char Darkness[33][256];
  5.  
  6. inline int LeftSection();
  7. inline int RightSection();
  8. int shl10idiv(int x, int y);
  9. void InnerLoop(char *Screen, char *Bitmap, int u, int v, int c, int width);
  10. int CalcGVect(POLYGON *p);
  11.  
  12. // Some globals to interface with the left and right section functions
  13. VERTEX *lva[3], *rva[3];
  14. FPOINT *lpa[3], *rpa[3];
  15. int ls, rs, lsh, rsh;
  16. int lu, dlu, lv, dlv, lc, dlc;
  17. int lx, dlx, rx, drx;
  18. int dudx, dvdx, dcdx;
  19.     
  20. int WORLD::DrawTriangle(POLYGON *p, void *Screen)
  21. {
  22.     VERTEX    *v1, *v2, *v3, *tv;
  23.     FPOINT    *p1, *p2, *p3, *tp;
  24.     int        height, temp, longest;
  25.     char    *scrptr, *scrtemp;
  26.     int        x1, width, index;
  27.     int        u, v, ys, ye, i, c;
  28.     char    *bitmap;
  29.     
  30.     CalcGVect(p);
  31.     v1 = &p->Vertex[0]; v2 = &p->Vertex[1]; v3 = &p->Vertex[2];
  32.     p1 = &p->TextPt[0]; p2 = &p->TextPt[1];    p3 = &p->TextPt[2];
  33.  
  34.     if(v1->sy > v2->sy)
  35.     {
  36.         tv = v1; v1 = v2; v2 = tv;
  37.         tp = p1; p1 = p2; p2 = tp;
  38.     }
  39.     if(v1->sy > v3->sy)
  40.     {
  41.         tv = v1; v1 = v3; v3 = tv;
  42.         tp = p1; p1 = p3; p3 = tp;
  43.     }
  44.     if(v2->sy > v3->sy)
  45.     {
  46.         tv = v2; v2 = v3; v3 = tv;
  47.         tp = p2; p2 = p3; p3 = tp;
  48.     }
  49.  
  50.     height = v3->sy - v1->sy;
  51.     if(!height) return 0;
  52.     temp = ((v2->sy - v1->sy) << 16) / height;
  53.     longest = temp * (v3->sx - v1->sx) + ((v1->sx - v2->sx) << 16);
  54.     if(!longest) return 0;
  55.  
  56. // Vertices now sorted and the length of the longest scanline is calculated
  57.  
  58.     if(longest < 0)
  59.     {
  60.         rva[0] = v3; rva[1] = v2; rva[2] = v1; rs = 2;
  61.         lva[0] = v3; lva[1] = v1; ls = 1;
  62.         rpa[0] = p3; rpa[1] = p2; rpa[2] = p1;
  63.         lpa[0] = p3; lpa[1] = p1;
  64.     
  65.         if(LeftSection() <= 0)
  66.             return 0;
  67.         if(RightSection() <= 0)
  68.         {
  69.             rs--;
  70.             if(RightSection() <= 0)
  71.                 return 0;
  72.         }
  73.         if(longest > -0x1000) longest = -0x1000;
  74.     }
  75.  
  76.     else
  77.     {
  78.         lva[0] = v3; lva[1] = v2; lva[2] = v1; ls = 2;
  79.         rva[0] = v3; rva[1] = v1; rs = 1;
  80.         lpa[0] = p3; lpa[1] = p2; lpa[2] = p1;
  81.         rpa[0] = p3; rpa[1] = p1;
  82.  
  83.         if(RightSection() <= 0)
  84.             return 0;
  85.         if(LeftSection() <= 0)
  86.         {
  87.             ls--;
  88.             if(LeftSection() <= 0)
  89.                 return 0;
  90.         }
  91.         if(longest < 0x1000) longest = 0x1000;
  92.     }
  93.  
  94.     dudx = shl10idiv(temp * (p3->x - p1->x) + ((p1->x - p2->x) << 16),
  95.                      longest);
  96.     dvdx = shl10idiv(temp * (p3->y - p1->y) + ((p1->y - p2->y) << 16),
  97.                      longest);
  98.     dcdx = shl10idiv(temp * (v3->Vect - v1->Vect) + ((v1->Vect - v2->Vect) << 16),
  99.                      longest);
  100.     ys = v1->sy; ye = v3->sy;
  101.     if(ye > 416) ye = 416;
  102.     scrptr = (char *)Screen + ys * DD->Pitch;
  103.     bitmap = (char *)Texture[0].Data + ((p->Texture - 1) << 5);
  104.     for(i = ys; i < ye; i++)
  105.     {
  106. // Find and clip the scanlines
  107.         if(i >= 0)
  108.         {
  109.             u = lu; v = lv;
  110.             c = lc;
  111.             x1 = lx >> 16;
  112.  
  113.             if(x1 < 0)
  114.             {
  115.                 while(x1 < 0)
  116.                 {
  117.                     u += dudx;
  118.                     v += dvdx;
  119.                     c += dcdx;
  120.                     x1++;
  121.                 }
  122.             }
  123.             width = (rx >> 16) - x1;
  124.             if((x1 + width) > 640)
  125.                 width -= (x1 + width) - 640;
  126.             scrtemp = scrptr + x1;
  127.  
  128.             if(width > 0)
  129.                 InnerLoop(scrtemp, bitmap, u, v, c, width);
  130.         }
  131.  
  132.         scrptr += DD->Pitch;
  133.  
  134.         if(--lsh <= 0)
  135.         {
  136.             if(--ls <= 0) return 0;
  137.             if(LeftSection() <= 0)
  138.                 return 0;
  139.         }
  140.         else
  141.         {
  142.             lx += dlx; lu += dlu; lv += dlv; lc += dlc;
  143.         }
  144.  
  145.         if(--rsh <= 0)
  146.         {
  147.             if(--rs <= 0) return 0;
  148.             if(RightSection() <= 0)
  149.                 return 0;
  150.         }
  151.         else
  152.         {
  153.             rx += drx;
  154.         }
  155.     }
  156.  
  157.     return 0;
  158. };
  159.  
  160. inline int LeftSection()
  161. {
  162.     VERTEX    *v1, *v2;
  163.     FPOINT    *p1, *p2;
  164.     int     height;
  165.     
  166.     v1 = lva[ls]; v2 = lva[ls - 1];
  167.     p1 = lpa[ls]; p2 = lpa[ls - 1];
  168.     height = v2->sy - v1->sy;
  169.     if(!height) return 0;
  170.  
  171.     dlx = ((v2->sx - v1->sx) << 16);
  172.     lx = v1->sx << 16;
  173.     dlu = ((p2->x - p1->x) << 16);
  174.     lu = p1->x << 16;
  175.     dlv = ((p2->y - p1->y) << 16);
  176.     lv = p1->y << 16;
  177.     dlc = ((v2->Vect - v1->Vect) << 16);
  178.     lc = v1->Vect << 16;
  179.     if(height == 2) { dlx >>= 1; dlu >>= 1; dlv >>= 1; dlc >>= 1;}
  180.     else if(height == 4) { dlx >>= 2; dlu >>= 2; dlv >>= 2; dlc >>= 2;}
  181.     else if(height == 8) { dlx >>= 3; dlu >>= 3; dlv >>= 3; dlc >>= 3;}
  182.     else { dlx /= height; dlu /= height; dlv /= height; dlc /= height;}
  183.     lsh = height;
  184.     return height;
  185. };
  186.  
  187. inline int RightSection()
  188. {
  189.     VERTEX    *v1, *v2;
  190.     int     height;
  191.  
  192.     v1 = rva[rs]; v2 = rva[rs - 1];
  193.     height = v2->sy - v1->sy;
  194.     if(!height) return 0;
  195.  
  196.     drx = ((v2->sx - v1->sx) << 16) / height;
  197.     rx = v1->sx << 16;
  198.     rsh = height;
  199.     return height;
  200. };
  201.  
  202. void InnerLoop(char *Screen, char *Bitmap, int u, int v, int c, int width)
  203. {
  204.     do
  205.     {
  206.         *Screen++ = Darkness[c >> 16][*(Bitmap + ((v >> 16) << 9) + (u >> 16))];
  207.         u += dudx;
  208.         v += dvdx;
  209.         c += dcdx;
  210.     } while(--width);
  211. };
  212.  
  213. #pragma aux shl10idiv = \
  214.     "mov edx, eax"\
  215.     "sar edx, 16"\
  216.     "shl eax, 16"\
  217.     "idiv ebx"\
  218.     "shld edx, eax, 16"\
  219.     parm [eax][ebx]\
  220.     modify exact [eax edx]\
  221.     value [eax]
  222.  
  223. int CalcGVect(POLYGON *p)
  224. {
  225.     float src;
  226.     float dist;
  227.     int tmp, i, j;
  228.     
  229.     for(i = 0; i < p->Number_Vertices; i++)
  230.     {
  231.         dist = p->Vertex[i].vz;
  232.         tmp = (int)(dist - 4096.0);
  233.         if(tmp < 0) tmp = 0;
  234.         tmp >>= 8;
  235.         j = p->Vertex[i].Vect - tmp;
  236.         if(j < 0) j = 0;
  237.         p->Vertex[i].Vect = j;
  238.     }
  239.     
  240.     return(0);
  241. };
  242.  
  243.